/**
 * @(#)EntityUtil.java 1.0 2016年4月8日
 * @Copyright:  Copyright 2016 - 2016 Meyli. Co. Ltd. All Rights Reserved.
 * @Description: 
 * 
 * Modification History:
 * Date:        2016年4月8日
 * Author:      gaobo
 * Version:     V1.0.0.1
 * Description: (Initialize)
 * Reviewer:    
 * Review Date: 
 */
package com.ztmg.water.util;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

/**
 * Copyright:   Copyright 2016 - 2016 Meyli. Co. Ltd. All Rights Reserved.
 * Date:        2016年4月8日 下午1:25:06
 * Author:      gaobo
 * Version:     V1.0.0.1
 * Description: 生成mybaitisxml文件，实体，接口
 */
public class BuilderMybaitis
{
    private final String type_char = "char";
    
    private final String type_date = "date";
    
    private final String type_timestamp = "timestamp";
    
    private final String type_int = "int";
    
    private final String type_bigint = "bigint";
    
    private final String type_text = "text";
    
    private final String type_bit = "bit";
    
    private final String type_decimal = "decimal";
    
    private final String type_blob = "blob";
    
    private String pro_dir = "D:/es_app/trunk/api/es-api/";
    
    private String java_path = "src/com/meyki/api/";
    
    private String bean_dir = "domain";
    
    private String mapper_dir = "mapper";
    
    private String service_dir ="service";
    private String serviceImpl_dir ="impl";
    
    private String controller_dir ="controller";
    
    private String xml_dir = "src/config/mapper/";
    
    private String bean_path = "";
    
    private String mapper_path = "";
    
    private String xml_path = "";
    
    private String service_path = "";
    private String serviceImpl_path = "";
    
    private String controller_path = "";
    
    private String service_package = "";
    private String serviceImpl_package = "";
    
    private String controller_package = "";
    
    private String bean_package = "";
    
    private String mapper_package = "";
    
    private final String driverName = "com.mysql.jdbc.Driver";
    
    private final String user = "root";
    
    private final String password = "@#aobao123";
    
    private final String url = "jdbc:mysql://218.244.131.54:3306/" + "eseyapp"
        + "?characterEncoding=utf8";
    
    private String tableName = null;
    
    private String beanName = null;
    
    private String mapperName = null;
    
    private String serviceName = null;
    private String serviceImplName = null;
    private String controllerName = null;
    private Connection conn = null;
    
    private List<String> filterColumnList = Arrays.asList(
        new String[] {"creater", "create_time", "modifier", "modify_time" });
    
    private void init() throws ClassNotFoundException, SQLException
    {
        Class.forName(driverName);
        conn = DriverManager.getConnection(url, user, password);
    }
    
    /**
     *  获取所有的表
     *
     * @return
     * @throws SQLException 
     */
    private List<String> getTables() throws SQLException
    {
        List<String> tables = new ArrayList<String>();
        PreparedStatement pstate = conn.prepareStatement("show tables");
        ResultSet results = pstate.executeQuery();
        while (results.next())
        {
            String tableName = results.getString(1);
            //          if ( tableName.toLowerCase().startsWith("yy_") ) {
            tables.add(tableName);
            //          }
        }
        return tables;
    }
    
    private void processTable(String table)
    {
        StringBuffer sb = new StringBuffer(table.length());
        String tableNew = table.toLowerCase();
        String[] tables = tableNew.split("_");
        String temp = null;
        if (tables.length > 1)
        {
            for (int i = 1; i < tables.length; i++)
            {
                temp = tables[i].trim();
                sb.append(temp.substring(0, 1).toUpperCase())
                    .append(temp.substring(1));
            }
        }
        else
        {
            temp = tables[0].trim();
            sb.append(temp.substring(0, 1).toUpperCase())
                .append(temp.substring(1));
        }
        beanName = sb.toString();
        mapperName = beanName + "Mapper";
        serviceName = beanName +"Service";
        controllerName = beanName +"Controller";
        serviceImplName = beanName+"ServiceImpl";
    }
    
    private String processType(String type)
    {
        if (type.indexOf(type_char) > -1)
        {
            return "String";
        }
        else if (type.indexOf(type_bigint) > -1)
        {
            return "Long";
        }
        else if (type.indexOf(type_int) > -1)
        {
            return "Integer";
        }
        else if (type.indexOf(type_date) > -1)
        {
            return "java.util.Date";
        }
        else if (type.indexOf(type_text) > -1)
        {
            return "String";
        }
        else if (type.indexOf(type_timestamp) > -1)
        {
            return "java.util.Date";
        }
        else if (type.indexOf(type_bit) > -1)
        {
            return "Boolean";
        }
        else if (type.indexOf(type_decimal) > -1)
        {
            return "java.math.BigDecimal";
        }
        else if (type.indexOf(type_blob) > -1)
        {
            return "byte[]";
        }
        return null;
    }
    
    private String processField(String field)
    {
        StringBuffer sb = new StringBuffer(field.length());
        //field = field.toLowerCase();
        String[] fields = field.toLowerCase().split("_");
        String temp = null;
        sb.append(fields[0]);
        for (int i = 1; i < fields.length; i++)
        {
            temp = fields[i].trim();
            sb.append(temp.substring(0, 1).toUpperCase())
                .append(temp.substring(1));
        }
        return sb.toString();
    }
    
    /**
     *  将实体类名首字母改为小写
     *
     * @param beanName
     * @return 
     */
    private String processResultMapId(String beanName)
{
    return beanName.substring(0, 1).toLowerCase() + beanName.substring(1);
}
    
    /**
     *  构建类上面的注释
     *
     * @param bw
     * @param text
     * @return
     * @throws IOException 
     */
    private BufferedWriter buildClassComment(BufferedWriter bw, String text)
        throws IOException
    {
        bw.newLine();
        bw.newLine();
        bw.write("/**");
        bw.newLine();
        bw.write(" * ");
        bw.newLine();
        bw.write(" * " + text);
        bw.newLine();
        bw.write(" * ");
        bw.newLine();
        bw.write(" **/");
        return bw;
    }
    
    /**
     *  构建方法上面的注释
     *
     * @param bw
     * @param text
     * @return
     * @throws IOException 
     */
    private BufferedWriter buildMethodComment(BufferedWriter bw, String text)
        throws IOException
    {
        bw.newLine();
        bw.write("\t/**");
        bw.newLine();
        bw.write("\t * ");
        bw.newLine();
        bw.write("\t * " + text);
        bw.newLine();
        bw.write("\t * ");
        bw.newLine();
        bw.write("\t **/");
        return bw;
    }
    
    /**
     *  生成实体类
     *
     * @param columns
     * @param types
     * @param comments
     * @throws IOException 
     */
    private void buildEntityBean(List<String> columns, List<String> types,
        List<String> comments, String tableComment) throws IOException
    {
        CreateFolders(bean_path);
        //        File folder = new File(bean_path);
        //        if (!folder.exists())
        //        {
        //            folder.mkdir();
        //        }
        
        File beanFile = new File(bean_path, beanName + ".java");
        BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(beanFile)));
        bw.write("package " + bean_package + ";");
        bw.newLine();
        bw.write("import com.meyki.common.domain.BaseEntity;");
        bw.newLine();
        //bw.write("import lombok.Data;");
        //      bw.write("import javax.persistence.Entity;");
        bw = buildClassComment(bw, tableComment);
        bw.newLine();
        bw.write("@SuppressWarnings(\"serial\")");
        bw.newLine();
        //      bw.write("@Entity");
        //bw.write("@Data");
        //bw.newLine();
        bw.write("public class " + beanName + " extends BaseEntity {");
        bw.newLine();
        bw.newLine();
        int size = columns.size();
        for (int i = 0; i < size; i++)
        {
            bw.write("\t/**" + comments.get(i) + "**/");
            bw.newLine();
            bw.write("\tprivate " + processType(types.get(i)) + " "
                + processField(columns.get(i)) + ";");
            bw.newLine();
            bw.newLine();
        }
        bw.newLine();
        // 生成get 和 set方法
        String tempField = null;
        String _tempField = null;
        String tempType = null;
        for (int i = 0; i < size; i++)
        {
            tempType = processType(types.get(i));
            _tempField = processField(columns.get(i));
            tempField = _tempField.substring(0, 1).toUpperCase()
                + _tempField.substring(1);
            bw.newLine();
            //          bw.write("\tpublic void set" + tempField + "(" + tempType + " _" + _tempField + "){");
            bw.write("\tpublic void set" + tempField + "(" + tempType + " "
                + _tempField + "){");
            bw.newLine();
            //          bw.write("\t\tthis." + _tempField + "=_" + _tempField + ";");
            bw.write("\t\tthis." + _tempField + " = " + _tempField + ";");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.newLine();
            bw.write("\tpublic " + tempType + " get" + tempField + "(){");
            bw.newLine();
            bw.write("\t\treturn this." + _tempField + ";");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
        }
        bw.newLine();
        
        bw.newLine();
        //toString方法
        bw.write("\t@Override");
        bw.newLine();
        bw.write("\tpublic String toString(){");
        bw.newLine();
        bw.write("\t\treturn \"" + beanName + "[");
        
        size = columns.size();
        for (int i = 0; i < size; i++)
        {
            if (i != size - 1)
            {
                bw.write(processField(columns.get(i)) + "=\" + "
                    + processField(columns.get(i)) + " + \" ,");
            }
            else
            {
                bw.write(processField(columns.get(i)) + "=\" + "
                    + processField(columns.get(i)) + " + \"]\";");
            }
        }
        bw.newLine();
        bw.write("\t}");
        bw.newLine();
        bw.write("}");
        bw.newLine();
        bw.flush();
        bw.close();
    }
    
    /**
     *  构建Mapper文件
     *
     * @throws IOException 
     */
    private void buildMapper() throws IOException
    {
        CreateFolders(mapper_path);
        
        File mapperFile = new File(mapper_path, mapperName + ".java");
        BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(mapperFile), "utf-8"));
        bw.write("package " + mapper_package + ";");
        bw.newLine();
        bw.newLine();
        // bw.write("import " + bean_package + "." + beanName + ";");
        // bw.newLine();
        bw.write("import java.io.Serializable;");
        bw.newLine();
        bw.write("import com.meyki.common.mapper.BaseMapper;");
        
        bw = buildClassComment(bw, mapperName + "数据库操作接口类");
        bw.newLine();
        bw.newLine();
        //      bw.write("public interface " + mapperName + " extends " + mapper_extends + "<" + beanName + "> {");
        bw.write("public interface " + mapperName
            + "<T,ID> extends BaseMapper<T,Serializable>{");
        bw.newLine();
        bw.newLine();
        /*      
        // ----------定义Mapper中的方法Begin----------
        bw = buildMethodComment(bw, "查询（根据主键ID查询）");
        bw.newLine();
        bw.write("\t" + beanName
            + "  selectByPrimaryKey ( @Param(\"id\") Long id );");
        bw.newLine();
        bw = buildMethodComment(bw, "删除（根据主键ID删除）");
        bw.newLine();
        bw.write("\t" + "int deleteByPrimaryKey ( @Param(\"id\") Long id );");
        bw.newLine();
        bw = buildMethodComment(bw, "添加");
        bw.newLine();
        bw.write("\t" + "int insert( " + beanName + " record );");
        bw.newLine();
        bw = buildMethodComment(bw, "添加 （匹配有值的字段）");
        bw.newLine();
        bw.write("\t" + "int insertSelective( " + beanName + " record );");
        bw.newLine();
        bw = buildMethodComment(bw, "修改 （匹配有值的字段）");
        bw.newLine();
        bw.write("\t" + "int updateByPrimaryKeySelective( " + beanName
            + " record );");
        bw.newLine();
        bw = buildMethodComment(bw, "修改（根据主键ID修改）");
        bw.newLine();
        bw.write("\t" + "int updateByPrimaryKey ( " + beanName + " record );");
        bw.newLine();
        
        // ----------定义Mapper中的方法End----------
        */
        bw.newLine();
        bw.write("}");
        bw.flush();
        bw.close();
    }
    
    /**
     *  构建实体类映射XML文件
     *
     * @param columns
     * @param types
     * @param comments
     * @throws IOException 
     */
    private void buildMapperXml(List<String> columns, List<String> types,
        List<String> comments) throws IOException
    {
        CreateFolders(xml_path);
        File mapperXmlFile = new File(xml_path, mapperName + ".xml");
        
        BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(mapperXmlFile)));
        bw.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        bw.newLine();
        bw.write(
            "<!DOCTYPE mapper PUBLIC \"-//mybatis.org//DTD Mapper 3.0//EN\" ");
        bw.newLine();
        bw.write("    \"http://mybatis.org/dtd/mybatis-3-mapper.dtd\">");
        bw.newLine();
        bw.write(
            "<mapper namespace=\"" + mapper_package + "." + mapperName + "\">");
        bw.newLine();
        bw.newLine();
        
        // 下面开始写SqlMapper中的方法
        // this.outputSqlMapperMethod(bw, columns, types);
        buildSQL(bw, columns, types, comments);
        
        bw.write("</mapper>");
        bw.flush();
        bw.close();
    }
    
    private void buildSQL(BufferedWriter bw, List<String> columns,
        List<String> types, List<String> comments) throws IOException
    {
        int size = columns.size();
        
        bw.write("\t<!--实体映射-->");
        bw.newLine();
        bw.write("\t<resultMap id=\"" + this.processResultMapId(beanName)
            + "ResultMap\" type=\"" + bean_package + "." + beanName + "\">");
        bw.newLine();
        bw.write("\t\t<!--" + comments.get(0) + "-->");
        bw.newLine();
        bw.write("\t\t<id property=\"" + this.processField(columns.get(0))
            + "\" column=\"" + columns.get(0) + "\" />");
        bw.newLine();
        for (int i = 1; i < size; i++)
        {
            bw.write("\t\t<!--" + comments.get(i) + "-->");
            bw.newLine();
            bw.write(
                "\t\t<result property=\"" + this.processField(columns.get(i))
                    + "\" column=\"" + columns.get(i) + "\" />");
            bw.newLine();
        }
        bw.write("\t</resultMap>");
        
        bw.newLine();
        bw.newLine();
        
        // 通用结果列
        bw.write("\t<!-- 通用查询结果列-->");
        bw.newLine();
        bw.write("\t<sql id=\"Base_Column_List\">");
        bw.newLine();
        
        bw.write("\t\t id,");
        for (int i = 1; i < size; i++)
        {
            bw.write("\t" + columns.get(i));
            if (i != size - 1)
            {
                bw.write(",");
            }
        }
        
        bw.newLine();
        bw.write("\t</sql>");
        bw.newLine();
        bw.newLine();
        
        // 查询（根据主键ID查询）
        bw.write("\t<!-- 查询（根据主键ID查询） -->");
        bw.newLine();
        bw.write("\t<select id=\"getSingleByID\" resultMap=\""
            + this.processResultMapId(beanName)
            + "ResultMap\" parameterType=\"java.lang."
            + processType(types.get(0)) + "\">");
        bw.newLine();
        bw.write("\t\t SELECT");
        bw.newLine();
        bw.write("\t\t <include refid=\"Base_Column_List\" />");
        bw.newLine();
        bw.write("\t\t FROM " + tableName);
        bw.newLine();
        bw.write("\t\t WHERE " + columns.get(0) + " = #{"
            + processField(columns.get(0)) + "}");
        bw.newLine();
        bw.write("\t</select>");
        bw.newLine();
        bw.newLine();
        // 查询完
        // 根据条件查询 实体 开始
        bw.write("\t<!-- 查询（根据条件查询 实体） -->");
        bw.newLine();
        bw.write("\t<select id=\"getSingle\" resultMap=\""
            + this.processResultMapId(beanName) + "ResultMap\" parameterType=\""
            + bean_package + "." + beanName + "\">");
        bw.newLine();
        bw.write("\t\t SELECT");
        bw.newLine();
        bw.write("\t\t <include refid=\"Base_Column_List\" />");
        bw.newLine();
        bw.write("\t\t FROM " + tableName);
        bw.newLine();
        bw.write("\t\t <trim prefix=\"WHERE\" prefixOverrides=\"AND|OR\">");
        bw.newLine();
        String tempField = null;
        for (int i = 0; i < size; i++)
        {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"" + tempField + "!=null\">");
            bw.newLine();
            bw.write(
                "\t\t\t\t  AND " + columns.get(i) + "=#{" + tempField + "} ");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
        bw.write("\t\t</trim>");
        bw.newLine();
        bw.write("\t</select>");
        bw.newLine();
        bw.newLine();
        // 根据条件查询 实体 结束
        
        //根据条件查询实体列表 开始
        bw.write("\t<!-- 查询（按条件查询记录 ） -->");
        bw.newLine();
        bw.write("\t<select id=\"select\" resultMap=\""
            + this.processResultMapId(beanName) + "ResultMap\" parameterType=\""
            + "java.util.Map" + "\">");
        bw.newLine();
        bw.write("\t\t SELECT");
        bw.newLine();
        bw.write("\t\t <include refid=\"Base_Column_List\" />");
        bw.newLine();
        bw.write("\t\t FROM " + tableName);
        bw.newLine();
        bw.write("\t\t\t<trim prefix=\"WHERE\" prefixOverrides=\"AND|OR\">");
        bw.newLine();
        tempField = null;
        for (int i = 0; i < size; i++)
        {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"" + tempField + "!=null\">");
            bw.newLine();
            bw.write(
                "\t\t\t\t  AND " + columns.get(i) + "=#{" + tempField + "} ");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
        bw.write("\t\t\t</trim>");
        bw.newLine();
        bw.write("\t</select>");
        bw.newLine();
        bw.newLine();
        //根据条件查询实体列表 结束
        
        // 删除（根据主键ID删除）
        bw.write("\t<!--删除：根据主键ID删除-->");
        bw.newLine();
        bw.write("\t<delete id=\"deleteByID\" parameterType=\"java.lang."
            + processType(types.get(0)) + "\">");
        bw.newLine();
        bw.write("\t\t DELETE FROM " + tableName);
        bw.newLine();
        bw.write("\t\t WHERE " + columns.get(0) + " = #{"
            + processField(columns.get(0)) + "}");
        bw.newLine();
        bw.write("\t</delete>");
        bw.newLine();
        bw.newLine();
        // 删除完
        
        //  删除 根据条件删除 开始
        
        bw.write("\t<!-- 删除（根据条件删除） -->");
        bw.newLine();
        bw.write("\t<delete id=\"delete\" parameterType=\"" + bean_package + "."
            + beanName + "\">");
        bw.newLine();
        bw.write("\t\t DELETE FROM " + tableName);
        bw.newLine();
        bw.write("\t\t <trim prefix=\"WHERE\" prefixOverrides=\"AND|OR\">");
        bw.newLine();
        tempField = null;
        for (int i = 0; i < size; i++)
        {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"" + tempField + "!=null\">");
            bw.newLine();
            bw.write(
                "\t\t\t\t  AND " + columns.get(i) + "=#{" + tempField + "} ");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
        bw.write("\t\t\t</trim>");
        bw.newLine();
        bw.write("\t</delete>");
        bw.newLine();
        bw.newLine();
        //  删除 根据条件删除 结束
        
        //---------------  insert方法（匹配有值的字段）
        bw.write("\t<!-- 添加 （匹配有值的字段）-->");
        bw.newLine();
        bw.write("\t<insert id=\"insert\" parameterType=\"" + bean_package + "."
            + beanName + "\">");
        bw.newLine();
        bw.write("\t\t INSERT INTO " + tableName);
        bw.newLine();
        bw.write(
            "\t\t <trim prefix=\"(\" suffix=\")\" suffixOverrides=\",\" >");
        bw.newLine();
        
        tempField = null;
        for (int i = 0; i < size; i++)
        {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"" + tempField + " != null\">");
            bw.newLine();
            bw.write("\t\t\t\t " + columns.get(i) + ",");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
        
        bw.newLine();
        bw.write("\t\t </trim>");
        bw.newLine();
        
        bw.write(
            "\t\t <trim prefix=\"values (\" suffix=\")\" suffixOverrides=\",\" >");
        bw.newLine();
        
        tempField = null;
        for (int i = 0; i < size; i++)
        {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"" + tempField + "!=null\">");
            bw.newLine();
            bw.write("\t\t\t\t #{" + tempField + "},");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
        
        bw.write("\t\t </trim>");
        bw.newLine();
        bw.write("\t</insert>");
        bw.newLine();
        bw.newLine();
        //---------------  完毕
        
        // 修改update方法
        bw.write("\t<!-- 修 改-->");
        bw.newLine();
        bw.write("\t<update id=\"update\" parameterType=\"" + bean_package + "."
            + beanName + "\">");
        bw.newLine();
        bw.write("\t\t UPDATE " + tableName);
        bw.newLine();
        //  bw.write(" \t\t <set> ");
        bw.write("\t\t <trim prefix=\"set\" suffixOverrides=\",\" >");
        bw.newLine();
        bw.newLine();
        
        tempField = null;
        for (int i = 1; i < size; i++)
        {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"" + tempField + " != null\">");
            bw.newLine();
            bw.write("\t\t\t\t " + columns.get(i) + " = #{" + tempField + "},");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
        bw.newLine();
        //bw.write(" \t\t </set>");
        bw.write("\t\t </trim>");
        bw.newLine();
        bw.write("\t\t WHERE " + columns.get(0) + " = #{"
            + processField(columns.get(0)) + "}");
        bw.newLine();
        bw.write("\t</update>");
        bw.newLine();
        bw.newLine();
        // update方法完毕
        
        //批量插入 开始
        //---------------  insert方法（批量插入）
        bw.write("\t<!-- 添加 （批量添加）-->");
        bw.newLine();
        bw.write("\t<insert id=\"batchInsert\" parameterType=\""
            + "java.util.List" + "\">");
        bw.newLine();
        bw.write("\t\t INSERT INTO " + tableName);
        bw.newLine();
        bw.write(
            "\t\t\t<trim prefix=\"(\" suffix=\") values \" suffixOverrides=\",\" >");
        bw.newLine();
        bw.write(
            "\t\t\t <foreach item=\"item\" index=\"index\" collection=\"list\" >");
        bw.newLine();
        bw.write(
            "\t\t\t\t<if test=\"index == 0\">");
        bw.newLine();
        tempField = null;
        for (int i = 0; i < size; i++)
        {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t\t\t<if test=\"item." + tempField + " != null\">");
            bw.newLine();
            bw.write("\t\t\t\t\t " + columns.get(i) + ",");
            bw.newLine();
            bw.write("\t\t\t\t\t</if>");
            bw.newLine();
        }
        bw.newLine();
        bw.write("\t\t\t\t</if>");
        bw.newLine();
        bw.write("\t\t\t </foreach>");
        bw.newLine();
        bw.write("\t\t </trim>");        
        
        bw.newLine();
        bw.write(
            "\t\t<foreach item=\"item\" index=\"index\" collection=\"list\" separator=\",\">");

        bw.newLine();
        
        bw.write(
            "\t\t <trim prefix=\"values (\" suffix=\")\" suffixOverrides=\",\" >");
        bw.newLine();
        
        tempField = null;
        for (int i = 0; i < size; i++)
        {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"item." + tempField + "!=null\">");
            bw.newLine();
            bw.write("\t\t\t\t #{item." + tempField + "},");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
        bw.write("\t\t </trim>");
        bw.newLine();
        bw.write("\t\t</foreach>");
        bw.newLine();
        bw.write("\t</insert>");
        bw.newLine();
        //批量插入 结束
        
        //批量修改 开始
        
        bw.write("\t<!-- 修 改(批量修改)-->");
        bw.newLine();
        bw.write("\t<update id=\"batchUpdate\" parameterType=\""
            + "java.util.List" + "\">");
        bw.newLine();
        
        bw.write(
            "\t\t<foreach item=\"item\" index=\"index\" collection=\"list\" separator=\";\">");
        bw.newLine();
        bw.write("\t\t UPDATE " + tableName);
        bw.newLine();
        //bw.write(" \t\t <set> ");
        bw.write("\t\t <trim prefix=\"set\" suffixOverrides=\",\" >");
        bw.newLine();
        
        tempField = null;
        for (int i = 1; i < size; i++)
        {
            tempField = processField(columns.get(i));
            bw.write("\t\t\t<if test=\"item." + tempField + " != null\">");
            bw.newLine();
            bw.write("\t\t\t\t " + columns.get(i) + " = #{item." + tempField + "},");
            bw.newLine();
            bw.write("\t\t\t</if>");
            bw.newLine();
        }
        bw.newLine();
        //bw.write(" \t\t </set>");
        bw.write("\t\t </trim>");
        bw.newLine();
        bw.write("\t\t WHERE " + columns.get(0) + " = #{"
            + processField(columns.get(0)) + "}");
        bw.newLine();
        bw.write("\t\t</foreach> ");
        bw.newLine();
        
        bw.write("\t</update>");
        bw.newLine();
        bw.newLine();
        //批量修改 结束
        
        //批量删除 开始
        bw.write("\t<!--删除：批量删除-->");
        bw.newLine();
        bw.write("\t<delete id=\"batchDelete\" parameterType=\""
            + "java.util.List" + "\">");
        bw.newLine();
        bw.write("\t\t DELETE FROM " + tableName);
        bw.newLine();
        bw.write("\t\t WHERE " + columns.get(0) + " in");
        bw.newLine();
        bw.write(
            "\t\t<foreach collection=\"list\" item=\"item\" open=\"(\" separator=\",\" close=\")\">");
        bw.newLine();
        bw.write("\t\t\t#{item." + processField(columns.get(0)) + "}");
        bw.newLine();
        bw.write("\t\t</foreach>");
        bw.newLine();
        bw.write("\t</delete>");
        bw.newLine();
        //批量删除 结束
        bw.newLine();
    }
    
    /**
     *  获取所有的数据库表注释
     *
     * @return
     * @throws SQLException 
     */
    private Map<String, String> getTableComment() throws SQLException
    {
        Map<String, String> maps = new HashMap<String, String>();
        PreparedStatement pstate = conn.prepareStatement("show table status");
        ResultSet results = pstate.executeQuery();
        while (results.next())
        {
            String tableName = results.getString("NAME");
            String comment = results.getString("COMMENT");
            maps.put(tableName, comment);
        }
        return maps;
    }
    
    public void buildService() throws IOException
    {
        
        CreateFolders(service_path);
        
        File serviceFile = new File(service_path, serviceName + ".java");
        BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(serviceFile), "utf-8"));
        bw.write("package " + service_package + ";");
        bw.newLine();
        bw.newLine();
        // bw.write("import " + bean_package + "." + beanName + ";");
        // bw.newLine();
        
        bw = buildClassComment(bw, serviceName + "Service接口类");
        bw.newLine();
        bw.newLine();
        //      bw.write("public interface " + mapperName + " extends " + mapper_extends + "<" + beanName + "> {");
        bw.write("public interface " + serviceName+"{");
        bw.newLine();
        bw.newLine();
        bw.write("}");
        bw.flush();
        bw.close();
        
    }
    public void buildServiceImpl() throws IOException
    {
        CreateFolders(serviceImpl_path);
        
        File serviceImplFile = new File(serviceImpl_path, serviceImplName + ".java");
        BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(serviceImplFile), "utf-8"));
        bw.write("package " + serviceImpl_package + ";");
        bw.newLine();
        bw.newLine();
        
        bw.write("import org.apache.log4j.Logger;");
        bw.newLine();
        bw.write("import org.springframework.beans.factory.annotation.Autowired;");
        bw.newLine();
        bw.write("import org.springframework.stereotype.Service;");
        bw.newLine();
        
        bw.write("import " + bean_package + "." + beanName + ";");
        bw.newLine();
        bw.write("import " + service_package + "." + serviceName + ";");
        bw.newLine();
        bw.write("import " + mapper_package + "." + mapperName + ";");
        bw.newLine();
        bw.write("import com.meyki.common.service.BaseService;");
        bw.newLine();
        
        bw = buildClassComment(bw, serviceName + "Service实现类");
        bw.newLine();
        bw.newLine();
        //      bw.write("public interface " + mapperName + " extends " + mapper_extends + "<" + beanName + "> {");
        bw.write("@Service");
        bw.newLine();
        bw.write("public class " + serviceImplName+" extends BaseService implements "+serviceName+"{");
        bw.newLine();
        bw.newLine();
        bw.newLine();
        bw.write("\tprivate static Logger log = Logger.getLogger("+serviceImplName+".class);");
        bw.newLine();
        bw.newLine();
        
        bw.newLine();
        bw.write("\t@Autowired");
        bw.newLine();
        bw.write("\tprivate "+mapperName+"<"+beanName+",Integer> "+processResultMapId(mapperName)+";");
        bw.newLine();
        bw.write("}");
        bw.flush();
        bw.close();
    }   
    public void buildController() throws IOException{

        CreateFolders(controller_path);
        
        File serviceImplFile = new File(controller_path, controllerName + ".java");
        BufferedWriter bw = new BufferedWriter(
            new OutputStreamWriter(new FileOutputStream(serviceImplFile), "utf-8"));
        bw.write("package " + controller_package + ";");
        bw.newLine();
        bw.newLine();
        
        bw.write("import org.apache.log4j.Logger;");
        bw.newLine();
        bw.write("import org.springframework.beans.factory.annotation.Autowired;");
        bw.newLine();
        bw.write("import org.springframework.context.annotation.Scope;");
        bw.newLine();
        bw.write("import org.springframework.stereotype.Controller;");
        bw.newLine();
        bw.write("import org.springframework.web.bind.annotation.PathVariable;");
        bw.newLine();
        bw.write("import org.springframework.web.bind.annotation.RequestMapping;");
        bw.newLine();
        bw.write("import org.springframework.web.bind.annotation.RequestMethod;");
        bw.newLine();
        bw.write("import org.springframework.web.bind.annotation.ResponseBody;");
        bw.newLine();
        bw.newLine();
        bw.write("import com.meyki.common.vo.Message;");
        bw.newLine();
        bw.write("import " + bean_package + "." + beanName + ";");
        bw.newLine();
        bw.write("import " + service_package + "." + serviceName + ";");
        bw.newLine();
        
        bw = buildClassComment(bw, controllerName + "Controller");
        bw.newLine();
        bw.newLine();
        bw.write("@Scope(\"prototype\")");
        bw.newLine();
        bw.write("@Controller");
        bw.newLine();
        bw.write("@RequestMapping(value = \"/"+processResultMapId(beanName)+"\")");
        bw.newLine();
        bw.write("public class " + controllerName+"{");
        bw.newLine();
        bw.newLine();
        bw.newLine();
        bw.write("\tprivate static Logger log = Logger.getLogger("+controllerName+".class);");
        bw.newLine();
        bw.newLine();
        
        bw.newLine();
        bw.write("\t@Autowired");
        bw.newLine();
        bw.write("\tprivate "+serviceName+" "+processResultMapId(serviceName)+";");
        bw.newLine();
        bw.write("}");
        bw.flush();
        bw.close();
    
    }
    /**
     * 
     * @param moduleName 模板名称
     * @param tableName 生成表名
     * @param proPath 项目目录
     * @throws ClassNotFoundException
     * @throws SQLException
     * @throws IOException
     */
    public void generate(String moduleName, String tableName)
        throws ClassNotFoundException, SQLException, IOException
    {
        init();
        initParameter(moduleName);
        String prefix = "show full fields from ";
        List<String> columns = null;
        List<String> types = null;
        List<String> comments = null;
        List<String> columns_bean = null;
        List<String> types_bean = null;
        List<String> comments_bean = null;
        PreparedStatement pstate = null;
        //List<String> tables = getTables();
        Map<String, String> tableComments = getTableComment();
        //        for (String table : tables)
        //        {
        columns = new ArrayList<String>();
        types = new ArrayList<String>();
        comments = new ArrayList<String>();
        columns_bean = new ArrayList<String>();
        types_bean = new ArrayList<String>();
        comments_bean = new ArrayList<String>();
        pstate = conn.prepareStatement(prefix + tableName);
        ResultSet results = pstate.executeQuery();
        while (results.next())
        {
            columns.add(results.getString("FIELD"));
            types.add(results.getString("TYPE"));
            comments.add(results.getString("COMMENT"));
            if (!filterColumnList.contains(results.getString("FIELD").trim()))
            {
                columns_bean.add(results.getString("FIELD"));
                types_bean.add(results.getString("TYPE"));
                comments_bean.add(results.getString("COMMENT"));
            }
        }
        this.tableName = tableName;
        processTable(tableName);
        String tableComment = tableComments.get(tableName);
        buildEntityBean(columns_bean, types_bean, comments_bean, tableComment);
        buildMapper();
        buildMapperXml(columns, types, comments);
        buildService();
        buildServiceImpl();
        buildController();
        //        }
        conn.close();
    }
    
    private void initParameter(String moduleName)
    {
        bean_path =
            pro_dir + java_path + moduleName + File.separator + bean_dir;
        mapper_path =
            pro_dir + java_path + moduleName + File.separator + mapper_dir;
        xml_path = pro_dir + xml_dir + moduleName;
        bean_package = "com.meyki.api." + moduleName + ".domain";
        mapper_package = "com.meyki.api." + moduleName + ".mapper";
        
        
        service_path = pro_dir + java_path + moduleName + File.separator + service_dir;
        serviceImpl_path = pro_dir + java_path + moduleName + File.separator + service_dir+ File.separator+serviceImpl_dir;
        
        service_package = "com.meyki.api." + moduleName + ".service";
        serviceImpl_package = "com.meyki.api." + moduleName + ".service.impl";
        
        controller_path = pro_dir + java_path + moduleName + File.separator + controller_dir;
        controller_package = "com.meyki.api." + moduleName + ".controller";
        
    }
    
    public void CreateFolders(final String folders)
    {
        StringTokenizer st = new StringTokenizer(folders, File.separator);
        StringBuilder sb = new StringBuilder();
        String osname = System.getProperty("os.name");
        if (osname.compareToIgnoreCase("linux") == 0)
            sb.append(File.separator);
        
        while (st.hasMoreTokens())
        {
            sb.append(st.nextToken());
            File file = new File(sb.toString());
            if (!file.exists())
                file.mkdir();
            sb.append(File.separator);
        }
        
    }
    
    public static void main(String[] args)
    {
        try
        {
            String moduleName = "goods";
            String tableName = "es_goods_history";
            new BuilderMybaitis().generate(moduleName, tableName);
            System.out.println("OK!");
        }
        catch (ClassNotFoundException e)
        {
            e.printStackTrace();
        }
        catch (SQLException e)
        {
            e.printStackTrace();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
}
